<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .map {
            width: 800px;
            height: 600px;
            background-color: #cccccc;
            position: relative;
        }
    </style>
    <!-- 1.在地图中产生随机的食物 -->
</head>

<body>
    <div class="map">
    </div>
    <script>
        //定义食物的构造函数  自调用函数 --自执行函数
        (function() {
            //添加一个 储存 食物的数组
            var arrFood = []

            function Food(x, y, weight, height, bgcolor) {
                this.x = x;
                this.y = y;
                this.weight = weight || '20';
                this.height = height || '20';
                this.bgcolor = bgcolor || 'green'
            }
            //初始化创建在 地图中
            Food.prototype.init = function(map) {
                remove()
                var div = document.createElement('div')
                div.style.position = 'absolute'
                this.x = (parseInt(Math.random() * (map.offsetWidth / this.weight)) * this.weight)
                this.y = (parseInt(Math.random() * (map.offsetHeight / this.height)) * this.height)
                div.style.left = this.x + 'px'
                div.style.top = this.y + 'px'
                div.style.width = this.weight + 'px'
                div.style.height = this.height + 'px'
                div.style.backgroundColor = this.bgcolor
                map.appendChild(div)
                    //把这个元素存入数组
                arrFood.push(div)
            }

            //清除食物，保证页面只有1个食物。或者小蛇吃了后，页面食物被清除
            function remove() {
                if (arrFood.length != []) {
                    arrFood[0].parentNode.removeChild(arrFood[0])
                    arrFood = []
                }
            }
            window.Food = Food;
        })();
        //定义小蛇的构造函数  自调用函数 --自执行函数
        ;
        (function() {
            var arrSnake = []
                //小蛇的构造函数
            function Snake(width, height, dirctor) {
                this.width = width || '20';
                this.height = height || '20';
                this.dirctor = dirctor || 'right'
                    //小蛇的身体,默认初始
                this.body = [{
                        x: 3,
                        y: 1,
                        color: 'red'
                    }, //头
                    {
                        x: 2,
                        y: 1,
                        color: 'orange'
                    }, //身体
                    {
                        x: 1,
                        y: 1,
                        color: 'orange'
                    }, //身体
                ]
            }
            // 创建小蛇
            Snake.prototype.init = function(map) {
                    remove()
                    for (var i = 0; i < this.body.length; i++) {
                        //创建小蛇身体
                        var div = document.createElement('div')
                            //为div添加样式属性
                        div.style.width = this.width + 'px'
                        div.style.height = this.height + 'px'
                        div.style.backgroundColor = this.body[i].color;
                        div.style.position = 'absolute';
                        div.style.top = this.body[i].y * this.height + 'px'
                        div.style.left = this.body[i].x * this.width + 'px'
                            //把小蛇的身体添加到map中
                        map.appendChild(div)
                        arrSnake.push(div)
                    }
                }
                //小蛇移动
            Snake.prototype.move = function(map, food) {
                    //修改小蛇身体的移动
                    var i = this.body.length - 1; //2
                    for (; i > 0; i--) {
                        this.body[i].x = this.body[i - 1].x
                        this.body[i].y = this.body[i - 1].y
                    }
                    //修改舌头的移动
                    switch (this.dirctor) {
                        case 'right':
                            this.body[0].x += 1;
                            break;
                        case 'left':
                            this.body[0].x -= 1;
                            break;
                        case 'top':
                            this.body[0].y -= 1;
                            break;
                        case 'bottom':
                            this.body[0].y += 1;
                            break;
                    }
                    //判断小蛇有没有迟到食物，小蛇头的坐标和食物的坐标
                    var headX = this.body[0].x * this.width
                    var headY = this.body[0].y * this.height
                    console.log(headX, food.x)
                    console.log(headY, food.y)
                    if (headX === food.x && headY === food.y) {
                        //获取小蛇最后的尾巴
                        var last = this.body[this.body.length - 1]
                            //把蛇尾复制加到小蛇的身体中
                        this.body.push({
                            x: last.x,
                            y: last.y,
                            color: last.color
                        })
                        food.init(map)
                    }
                }
                //删除之前的小蛇
            function remove() {
                var i = arrSnake.length - 1; //2
                for (; i >= 0; i--) {
                    //DOM操作，在父元素中删除子元素
                    arrSnake[i].parentNode.removeChild(arrSnake[i])
                    arrSnake.splice(i, 1)
                }
            }
            window.Snake = Snake
        }())

        //定义游戏对象 相当于 小蛇和食物属于游戏的对象 自调用函数 --自执行函数
        ;
        //需要哪些属性，应该直接放到构造函数中  
        (function() {
            function Game(map) {
                this.map = map
                this.food = new Food()
                this.snake = new Snake()
                that = this //改变this的指向
            }
            //初始化游戏
            Game.prototype.init = function() {
                    //初始化食物
                    this.food.init(this.map)
                        //添加一个方法 初始化这个方法 小蛇自己动
                    this.runSnake()
                        //监听控制小蛇的移动，改变小蛇的方向
                    this.bindSnake()
                }
                //小蛇运行的方法,去调用小蛇的移动
            Game.prototype.runSnake = function() {
                    var timer = setInterval(() => {
                        this.snake.init(this.map)
                        this.snake.move(this.map, this.food)
                            //小蛇装到墙游戏结束
                            //横坐标最大的范围
                        let maxX = this.map.offsetWidth / this.snake.width
                        if (this.snake.body[0].x >= maxX || this.snake.body[0].x < 0) {
                            clearInterval(timer)
                            alert('游戏结束')
                        }
                        //纵坐标最大的范围
                        let maxY = this.map.offsetHeight / this.snake.height
                        if (this.snake.body[0].y >= maxY || this.snake.body[0].y < 0) {
                            clearInterval(timer)
                            alert('游戏结束')
                        }
                    }, 150);
                }
                //添加键盘的控制方法，操作小蛇
            Game.prototype.bindSnake = function() {
                    document.addEventListener('keydown', function(e) {
                        switch (e.keyCode) {
                            case 37:
                                this.snake.dirctor = "left";

                                break;
                            case 38:
                                this.snake.dirctor = "top";
                                break;
                            case 39:
                                this.snake.dirctor = "right";

                                break;
                            case 40:
                                this.snake.dirctor = "bottom";

                                break;


                        }
                    }.bind(that), false)
                }
                //把构造函数放到全局的window中，便于全局调用

            window.Game = Game
        }())
        //外部调用游戏对象，开始游戏
        var g1 = new Game(document.querySelector('.map'))
        g1.init()
    </script>
</body>

</html>